#ifndef __HTTP_H__
#define __HTTP_H__
/**
*@param[in]     buffer: the buffer is received http context data
*@param[in]     size: the length of http context data 
*@param[in]     nitems: the http response header "Content-Length" value
*@param[in]     private_data: user private data
*/
typedef int (*client_response_cb)(char *buffer, int size, int nitems, void *private_data);
typedef void http_client;


enum {
	HTTPCLIENT_OPT_URL,                         /**< set url, support https url*/
	HTTPCLIENT_OPT_METHOD,                      /**< set http method, support GET/POST/PUT*/
	HTTPCLIENT_OPT_HTTP1_0,                     /**< set http version, support HTTP1.0 and HTTP1.1*/
	HTTPCLIENT_OPT_HTTPHEADER,                  /**< set http private header,our http stack already support Referer/Host/Authorization/User-Agent/Connection/cookie/Content-Length,
                                                this header is other http header,ex: Content-Type..., we call it private header */
	HTTPCLIENT_OPT_POSTDATA,                    /**< set http POST data*/
	HTTPCLIENT_OPT_POSTLENGTH,                  /**< set http POST data length*/
	HTTPCLIENT_OPT_RESPONSECB,                  /**< set http response callback,if http have context,the callback will be process*/
	HTTPCLIENT_OPT_RESPONSECB_DATA,             /**< set http user private data,the data can using in callback */
	HTTPCLIENT_OPT_AUTH_TYPE,                   /**< set http auth type,support base and digest */  
	HTTPCLIENT_OPT_AUTH_USERNAME,               /**< set http username to auth*/
	HTTPCLIENT_OPT_AUTH_PASSWORD,               /**< set http password to auth*/
	HTTPCLIENT_OPT_PDP_CID,                     /**< set tcp data transfer pdp channel,generally,user not set this*/
	HTTPCLIENT_OPT_BIND_PORT,                   /**< set http client bind tcp port*/
};

enum {
	HTTPCLIENT_GETINFO_RESPONSE_CODE,           /**< get HTTP response code, get the value is 200,404 ... */
	HTTPCLIENT_GETINFO_TCP_STATE,               /**< get HTTP tcp socket status, get the value is HTTP_TCP_NOT_ESTABLISHED or HTTP_TCP_ESTABLISHED*/
};

enum {
	HTTPCLIENT_REQUEST_GET,                 /**< HTTP GET request type */
	HTTPCLIENT_REQUEST_POST,                /**< HTTP POST request type */
	HTTPCLIENT_REQUEST_PUT,                 /**< HTTP PUT request type */
	HTTPCLIENT_REQUEST_MAX
};

enum {
	HTTP_AUTH_TYPE_BASE = 1,                /**< HTTP auth type,base type */
	HTTP_AUTH_TYPE_DIGEST                   /**< HTTP auth type,digest type */
};

enum {
	HTTP_TCP_NOT_ESTABLISHED = 0,           /**< HTTP socket current status,tcp not connecting */
	HTTP_TCP_ESTABLISHED                    /**< HTTP socket current status,tcp connecting */
};

/*
 * HTTP Error codes
 */
enum {
	HTTP_CLIENT_ERROR = -1,                 /**< HTTP internal error. */
	HTTP_CLIENT_OK = 0,                     /**< HTTP OK. */
	HTTP_CLIENT_BAD_SOCKET_ID,              /**< HTTP socket is invalid. */
	HTTP_CLIENT_NO_MEMORY,                  /**< HTTP allocation of memory failed. */
	HTTP_CLIENT_BAD_HTTP_REQUEST,           /**< HTTP request not support. */
	HTTP_CLIENT_SEND_FAILED,                /**< HTTP send data failed. */
	HTTP_CLIENT_RECV_FAILED,                /**< HTTP receive data failed. */
	HTTP_CLIENT_HEADER_SIZE_TOO_LARGE,      /**< HTTP receive header size too long. */
	HTTP_CLIENT_GET_INVALID_HEADER,         /**< HTTP receive header failed. */
	HTTP_CLIENT_PROCESS_HEADER_FAILED,      /**< HTTP process header failed. */
	HTTP_CLIENT_CALLBACK_FAILED,            /**< HTTP callback return failed. */
	HTTP_CLIENT_CREATE_SOCKET_FAILED,       /**< HTTP create socket failed. */
	HTTP_CLIENT_INVALID_LOCATION,           /**< HTTP location is invalid. */
	HTTP_CLIENT_ACTIVE_STOP,                /**< HTTP socket active be close. */
};


struct http_client_list {
	char * data;
	struct http_client_list * next;
};

/**
 * @brief        init http client.
 *
 * @param[in]    none.
 *
 * @return       If successful, the function returns the http client context. 
 *               Otherwise, NULL is returned.
 */

struct http_client * http_client_init(void);

/**
 * @brief        shut down to release http resources.
 *
 * @param[in]    client : The http client context.
 *
 * @return       none. 
 *               
 */
void http_client_shutdown(struct http_client * client);

/**
 * @brief        add user private HTTP header to list for send to http server.
 *
 * @param[in]    list : The private HTTP header list.
 * @param[in]    data : The private HTTP header data.
 *
 * @return       If successful, the function returns the list that added new data. 
 *               Otherwise, returns the old list.
 */
struct http_client_list * http_client_list_append(struct http_client_list * list, const char * data);

/**
 * @brief        delete user private HTTP header list to release resources.
 *
 * @param[in]    list : The private HTTP header list.
 *
 * @return       none. 
 *               
 */
void http_client_list_destroy(struct http_client_list * list);

/**
 * @brief        set http client parameters.
 *
 * @param[in]    client : The http client context.
 * @param[in]    tag : the parameter type.
 * @param[in]    ... : the parameter value.
 *
 * @return       If successful, the function returns (HTTP_CLIENT_OK)0. 
 *               Otherwise, (HTTP_CLIENT_ERROR)-1 is returned.
 */
int http_client_setopt(struct http_client * client, int tag, ...);

/**
 * @brief        http client perform,send and receive http data.
 *
 * @param[in]    client : The http client context.
 *
 * @return       If successful, the function returns (HTTP_CLIENT_OK)0. 
 *               Otherwise, HTTP Error codes or SSL Error codes is returned.
 */
int http_client_perform(struct http_client * client);

/**
 * @brief        get http client perform info.
 *
 * @param[in]    client : The http client context.
 * @param[in]    tag : support get response code(HTTPCLIENT_GETINFO_RESPONSE_CODE),tcp status(HTTPCLIENT_GETINFO_TCP_STATE),http response header(HTTPCLIENT_GETINFO_RESPONSE_HTTP_HEADER).
 * @param[in]    result : get the info value.
 *
 * @return       If successful, the function returns (HTTP_CLIENT_OK)0. 
 *               Otherwise, (HTTP_CLIENT_ERROR)-1 is returned.
 */
int http_client_getinfo(struct http_client * client, int tag, void *result);

/**
 * @brief        user active terminate http client.
 *
 * @param[in]    client : The http client context.
 *
 * @return       none. 
 *               
 */
void http_client_stop(struct http_client * client);

#endif
